package com.apexedu.eas.task;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.apexedu.eas.common.SysProperty;
import com.apexedu.eas.dao.impl.TyxXsyshjDao;
import com.apexedu.eas.entity.TyxDzjl;
import com.apexedu.eas.entity.TyxDzmxjl;
import com.apexedu.eas.util.DateUtil;
import com.apexedu.eas.util.HttpClientUtil;
import com.apexedu.eas.util.JasksonUtil;
import com.apexedu.eas.vo.request.ReconciliationAllReq;
import com.apexedu.eas.vo.request.ReconciliationDetailReq;
import com.apexedu.eas.vo.response.Bill;
import com.apexedu.eas.vo.response.Detail;
import com.apexedu.eas.vo.response.ReconciliationAllResp;
import com.apexedu.eas.vo.response.ReconciliationDetailResp;
import com.apexedu.util.StringUtil;
import com.sun.tools.apt.Main;

import cn.com.sr.commonj.encrypt.jdk.MD5Util;

@Component
public class PayTask {
	private Logger log = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private TyxXsyshjDao payDao;
	
	@Scheduled(cron="0 0 1 * * ?") 
	//@Scheduled(cron="0/10 * * * * ? ") 
	@Transactional
	public void reconciliation (){
		log.debug("reconciliation start");
		Calendar date = Calendar.getInstance();
		date.setTime(new Date());
		date.set(Calendar.DATE, date.get(Calendar.DATE) - 1);
		String reconciliationDate = DateUtil.getDateFormat(date.getTime(),"yyyyMMdd");
		//String reconciliationDateStr = DateUtil.getDateFormat(date.getTime()); //yyyy-MM-dd
		log.debug("reconciliation date :{} " , reconciliationDate);
		//设置对账日期
		ReconciliationAllReq req =new ReconciliationAllReq();
		req.setBegindate(reconciliationDate);
		req.setEnddate(reconciliationDate);
		reconciliationCompare(req);
		log.debug("reconciliation end");
	}
	private boolean reconciliationCheck(String yxxt , String yl){
		BigDecimal a = new BigDecimal(yxxt);
		BigDecimal b = new BigDecimal(yl);
		if(a.compareTo(b)!=0)
			return false;
		return true;
	}
	
	@Transactional
	public void reconciliationCompare (ReconciliationAllReq req){
		String body = JasksonUtil.getJSONString(req);
		log.debug("报文主体：{} " , body);
		//all
		Map<String, String> args =new HashMap<String, String>();
		String signature = StringUtil.lowerCase(MD5Util.encrypt(body+SysProperty.securetKey));
		args.put("json", body);
		args.put("signature", signature);
		log.debug("报文主体：{} " , body);
		log.debug("报文签名：{} " , signature);
		log.debug("最终发送报文：{}" , JasksonUtil.getJSONString(args));
		String resp = HttpClientUtil.request(SysProperty.reconciliationUrl+"/tradeStatistiCollect", args, true);
		//请求到数据
		log.debug("获取到对账数据：{} " ,resp);
		Date now =new Date();  //证明是同一批插入的数据
		ReconciliationAllResp all = JasksonUtil.getDTO(resp, ReconciliationAllResp.class);
		if(!"0".equals(all.getRespcode())){
			log.error("获取银联数据失败！ 开始日期:{}  结束日期:{} 错误描述：{}",req.getBegindate() ,req.getEnddate(),all.getRespdesc());
			return;
		}
		List<Bill> bills = all.getData();
		for (Bill b : bills) {
			long dzjlId = Long.valueOf(payDao.getNextId("TYX_DZJL").toString());
			TyxDzjl dzjl =new TyxDzjl(dzjlId);
			
			Bill yxxt = payDao.getBillBySettledate(b.getDate()); //yyyy-MM-dd
			//对账开始
			log.debug("开始对账,日期：{}" ,b.getDate());
			boolean amtFlag = reconciliationCheck(yxxt.getAmt() , b.getAmt());
			boolean numFlag =  reconciliationCheck(yxxt.getNum() , b.getNum());
			if(!amtFlag){
				log.debug("总金额不平 ，迎新系统数据：{} ， 银联数据：{}" , yxxt.getAmt() , b.getAmt());
			}
			if(!numFlag){
				log.debug("总数量不平 ，迎新系统数据：{} ， 银联数据：{}" , yxxt.getNum() , b.getNum());
			}
			if(amtFlag&&numFlag){
				dzjl.setDzjg(1l);
				log.debug("日期：{} 对账数据已对平！" , b.getDate());
			}else{
				dzjl.setDzjg(0l);
				log.debug("日期：{} 对账数据不平！" , b.getDate());
			}
			//保存数据
			dzjl.setTjsj(now);
			dzjl.setYxxtje(Double.valueOf(yxxt.getAmt()));
			dzjl.setYxxtjfbs(Long.valueOf(yxxt.getNum()));
			dzjl.setYlxtje(Double.valueOf(b.getAmt()));
			dzjl.setYlxtjfbs(Long.valueOf(b.getNum()));
			dzjl.setDzrq(Integer.valueOf(changeDate(b.getDate())));
			payDao.addDzjl(dzjl);
			
			//对比详细数据
			args=new HashMap<String, String>();
			ReconciliationDetailReq detailReq = new ReconciliationDetailReq(changeDate(b.getDate()));
			body = JasksonUtil.getJSONString(detailReq);
			signature = MD5Util.encrypt(body+SysProperty.securetKey);
			args.put("json",body);
			args.put("signature", StringUtil.lowerCase(signature));
			resp = HttpClientUtil.request(SysProperty.reconciliationUrl+"/tradeStatistiDetail", args, true);
			ReconciliationDetailResp detailResp = JasksonUtil.getDTO(resp, ReconciliationDetailResp.class);
			if(!"0".equals(detailResp.getRespcode())){
				log.error("获取银联数据失败！ 日期:{}  错误描述：{}",b.getDate() ,detailResp.getRespdesc());
				return;
			}
			List<Detail> details  = detailResp.getData();
			for (Detail d : details) {
				long dzmxjlId = Long.valueOf(payDao.getNextId("TYX_DZMXJL").toString());
				TyxDzmxjl dzmxjl =new TyxDzmxjl(dzmxjlId);
				
				Detail detail = payDao.getDetailByOrderNo(d.getOrder_no()); //订单号
				//对账开始
				log.debug("开始明细对账,日期：{}" ,b.getDate());
				amtFlag = reconciliationCheck(detail.getAmt() , d.getAmt());
				if(!amtFlag){
					log.debug("实收金额不平 ，迎新系统数据：{} ， 银联数据：{}" , detail.getAmt() , d.getAmt());
				}
				if(amtFlag){
					dzmxjl.setDzjg(1l);
					log.debug("订单号：{} 对账数据已对平！" , detail.getOrder_no());
				}else{
					dzjl.setDzjg(0l);
					log.debug("订单号：{} 对账数据不平！" , detail.getOrder_no());
				}
				//保存数据
				dzmxjl.setDdh(d.getOrder_no());
				dzmxjl.setDzrq(Integer.valueOf(changeDate(b.getDate())));
				dzmxjl.setTjsj(now);
				dzmxjl.setYxxtje(Double.valueOf(detail.getAmt()));
				dzmxjl.setYlxtje(Double.valueOf(d.getAmt()));
				payDao.addDzmxjl(dzmxjl);
				//结束
			}
			
		}
		
		
		
	}
	
	private static String changeDate(String date){
		//if(date!=null &&date.length()==8){
		//	//return date.substring(0, 4)+"-"+date.substring(4, 6)+"-"+date.substring(6, 8);
		//}
		return date.replaceAll("-", "");
	}
}
